package speed2010.andreza.vspeed.gui;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.DebugGraphics;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.LayoutStyle;
import javax.swing.ListModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;

import prefuse.action.filter.GraphDistanceFilter;
import speed2010.andreza.vspeed.integration.CommunicationManager;
import speed2010.andreza.vspeed.query.QueryManager;
import speed2010.andreza.vspeed.util.Standards;
import speed2010.andreza.vspeed.util.SwingUtils;
import speed2010.andreza.vspeed.view.PrefuseConstants;
import speed2010.middleware.comunicacao.Address;
import speed2010.reformulacao.enums.EnrichmentType;
import speed2010.reformulacao.query.InstanceResult;
import speed2010.reformulacao.query.QueryResult;
import speed2010.util.SpeedLocalOntology;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import javax.swing.JTextField;
import java.awt.Point;

/**
 * @author <a href="mailto:andreza.lba@gmail.com">Andreza Leite de Alencar</a>
 */
public class PanelVisualQuery extends javax.swing.JPanel {
	private static final long serialVersionUID = 1L;

	private JTextArea txtAreaDL;

	private JTabbedPane jTabbedPane;

	private JScrollPane jScrollPaneHierarchicalView;
	private JScrollPane jScrollPaneGraphicalView;
	private JScrollPane jPanelDLtxt;
	private JScrollPane jScrollPaneResults;

	private PanelLegend jPanelLegend;

	private JPanel jPanelDireita;
	private JPanel jPanelConstructors;
	private JPanel jPanelDL;
	private JPanel jPaneltxtArea;
	private JPanel jPanelGraph;
	private JPanel jPanelProgressInfor;

	private PanelEnrichingVariables jPanelEnrichingVariables;
	private PanelQueryResults jPanelResults;
	private PanelDisplayGraph jPanelGraphDisplay;
	private PanelDeepControl jPanelDeepControl;

	private JList jListOntology;

	private JLabel jLabel1;
	private JLabel jLabelConstructors;

	private JButton jButtonSubmitQuery;
	private JButton jButtonNot;
	private JButton jButtonAnd;
	private JButton jButtonOr;
	private JButton jButtonClear;

	private final Vector<OntProperty> ontologyProperties = new Vector<OntProperty>();
	private ArrayList<String> arrayListOntologyElements;
	private final Vector<String> ontElementsVector = new Vector<String>();

	private JProgressBar jProgressBarResults;

	private final Object mutex = new Object();

	private QueryManager queryManager;
	private JTextField jTextFieldTTLIntra;
	private JTextField jTextFieldTTLInter;
	private JLabel jLabelTTLIntra;
	private JLabel jLabelTTLInter;

	public PanelVisualQuery() {
		super();
		initGUI();
		initializeOntology();
	}

	/**
	 * @return Returns the queryManager.
	 */
	public QueryManager getQueryManager() {
		return this.queryManager;
	}

	private void initGUI() {
		try {
			this.jPanelGraphDisplay = getJPanelGraphDisplay();

			final GroupLayout thisLayout = new GroupLayout(this);
			setLayout(thisLayout);
			setPreferredSize(new java.awt.Dimension(895, 626));
			{
				this.jPanelDireita = new JPanel();
				final GroupLayout gl_jPanelDireita = new GroupLayout(this.jPanelDireita);
				this.jPanelDireita.setLayout(gl_jPanelDireita);
				this.jPanelDireita.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
				{
					this.jLabel1 = new JLabel();
					this.jLabel1.setText("Select concepts from the ontology to compose your query");
					this.jLabel1.setHorizontalTextPosition(SwingConstants.CENTER);
					this.jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
					this.jLabel1.setFont(new java.awt.Font("Tahoma", 0, 10));
				}
				{
					this.jPanelEnrichingVariables = new PanelEnrichingVariables();
				}
				{
					this.jButtonSubmitQuery = new JButton();
					this.jButtonSubmitQuery.setText("Submit Query");
					this.jButtonSubmitQuery.setFont(new java.awt.Font("Tahoma", 1, 11));
					this.jButtonSubmitQuery.addMouseListener(new java.awt.event.MouseAdapter() {
						@Override
						public void mouseClicked(final java.awt.event.MouseEvent e) {
							submitQueryDL();
						}
					});
				}
				gl_jPanelDireita.setHorizontalGroup(gl_jPanelDireita
						.createSequentialGroup()
						.addContainerGap()
						.addGroup(
								gl_jPanelDireita
								.createParallelGroup()
								.addGroup(
										GroupLayout.Alignment.LEADING,
										gl_jPanelDireita
										.createSequentialGroup()
										.addComponent(this.jLabel1, 0, 321, Short.MAX_VALUE)
										.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
										.addComponent(getJButtonClear(), GroupLayout.PREFERRED_SIZE,
												94, GroupLayout.PREFERRED_SIZE).addGap(7))
												.addComponent(this.jPanelEnrichingVariables, GroupLayout.Alignment.LEADING, 0,
														432, Short.MAX_VALUE)
														.addComponent(getJPanelDL(), GroupLayout.Alignment.LEADING, 0, 432,
																Short.MAX_VALUE)
																.addComponent(getJScrollPaneResults(), GroupLayout.Alignment.LEADING, 0, 432,
																		Short.MAX_VALUE)
																		.addComponent(getJPanelProgressInfor(), GroupLayout.Alignment.LEADING, 0, 432,
																				Short.MAX_VALUE)
																				.addGroup(
																						GroupLayout.Alignment.LEADING,
																						gl_jPanelDireita
																						.createSequentialGroup()
																						.addGap(0, 262, Short.MAX_VALUE)
																						.addComponent(this.jButtonSubmitQuery,
																								GroupLayout.PREFERRED_SIZE, 158,
																								GroupLayout.PREFERRED_SIZE).addGap(12))));
				gl_jPanelDireita.setVerticalGroup(gl_jPanelDireita
						.createSequentialGroup()
						.addGap(6)
						.addGroup(
								gl_jPanelDireita
								.createParallelGroup()
								.addGroup(
										GroupLayout.Alignment.LEADING,
										gl_jPanelDireita
										.createSequentialGroup()
										.addComponent(this.jLabel1, GroupLayout.PREFERRED_SIZE,
												GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
												.addGap(10))
												.addComponent(getJButtonClear(), GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE,
														GroupLayout.PREFERRED_SIZE))
														.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
														.addComponent(getJPanelDL(), GroupLayout.PREFERRED_SIZE, 139, GroupLayout.PREFERRED_SIZE)
														.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
														.addComponent(this.jPanelEnrichingVariables, GroupLayout.PREFERRED_SIZE, 149,
																GroupLayout.PREFERRED_SIZE)
																.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
																.addComponent(this.jButtonSubmitQuery, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE,
																		GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent(getJScrollPaneResults(), 0, 181, Short.MAX_VALUE)
																		.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
																		.addComponent(getJPanelProgressInfor(), GroupLayout.PREFERRED_SIZE, 31,
																				GroupLayout.PREFERRED_SIZE).addContainerGap(17, 17));
			}
			{
				this.jTabbedPane = new JTabbedPane();
				{
					this.jScrollPaneGraphicalView = new JScrollPane();
					this.jTabbedPane.addTab("Graphical view", null, this.jScrollPaneGraphicalView, null);
					this.jScrollPaneGraphicalView.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
					this.jScrollPaneGraphicalView.setViewportView(getJPanelGraph());
				}
				{
					this.jScrollPaneHierarchicalView = new JScrollPane();
					this.jTabbedPane.addTab("Hierarchical view", null, this.jScrollPaneHierarchicalView, null);
					this.jScrollPaneHierarchicalView.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
					{
						final ListModel jListOntologyModel = new DefaultComboBoxModel(new String[]{});
						this.jListOntology = new JList();
						this.jScrollPaneHierarchicalView.setViewportView(this.jListOntology);
						this.jListOntology.setModel(jListOntologyModel);
						this.jListOntology.setDebugGraphicsOptions(DebugGraphics.BUFFERED_OPTION);
						this.jListOntology.setValueIsAdjusting(true);
					}
				}
			}
			thisLayout.setVerticalGroup(thisLayout
					.createSequentialGroup()
					.addContainerGap()
					.addGroup(
							thisLayout
							.createParallelGroup()
							.addComponent(this.jTabbedPane, GroupLayout.Alignment.LEADING, 0, 684,
									Short.MAX_VALUE)
									.addGroup(
											GroupLayout.Alignment.LEADING,
											thisLayout.createSequentialGroup().addGap(12)
											.addComponent(this.jPanelDireita, 0, 672, Short.MAX_VALUE))));
			thisLayout.setHorizontalGroup(thisLayout.createSequentialGroup().addContainerGap()
					.addComponent(this.jTabbedPane, 0, 423, Short.MAX_VALUE)
					.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
					.addComponent(this.jPanelDireita, 0, 446, Short.MAX_VALUE).addContainerGap());
			// cursor para inserção dos constructors DL na formulação da query

			this.jButtonNot.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
			this.jButtonNot.addMouseListener(new java.awt.event.MouseAdapter() {
				@Override
				public void mouseClicked(final java.awt.event.MouseEvent e) {
					PanelVisualQuery.this.txtAreaDL.append(Standards.NOT_UNICODE);
				}
			});

			this.jButtonAnd.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
			this.jButtonAnd.addMouseListener(new java.awt.event.MouseAdapter() {
				@Override
				public void mouseClicked(final java.awt.event.MouseEvent e) {
					PanelVisualQuery.this.txtAreaDL.append(" " + Standards.AND_UNICODE + " ");
				}
			});

			this.jButtonOr.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
			this.jButtonOr.addMouseListener(new java.awt.event.MouseAdapter() {
				@Override
				public void mouseClicked(final java.awt.event.MouseEvent e) {
					PanelVisualQuery.this.txtAreaDL.append(" " + Standards.OR_UNICODE + " ");
				}
			});

			this.jPaneltxtArea = getJPaneltxtArea();
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	private JPanel getJPaneltxtArea() {
		if (this.jPaneltxtArea == null) {
			this.jPaneltxtArea = new JPanel();
			this.jPaneltxtArea.setEnabled(false);
			{
				this.txtAreaDL = new JTextArea();
				this.jPaneltxtArea.add(this.txtAreaDL);
				this.jPanelDLtxt.setViewportView(getJPaneltxtArea());
				this.jPaneltxtArea.setPreferredSize(new java.awt.Dimension(302, 97));
				this.jPaneltxtArea.setBackground(new java.awt.Color(255, 255, 255));
				this.txtAreaDL.setPreferredSize(new java.awt.Dimension(299, 92));
				this.txtAreaDL.setEditable(false);
			}
		}
		return this.jPaneltxtArea;
	}

	private JPanel getJPanelDL() {
		if (this.jPanelDL == null) {
			this.jPanelDL = new JPanel();
			final GroupLayout gl_jPanelDL = new GroupLayout(this.jPanelDL);
			this.jPanelDL.setLayout(gl_jPanelDL);
			this.jPanelDL.setBackground(new java.awt.Color(255, 255, 255));
			this.jPanelDL.setBorder(BorderFactory.createTitledBorder(null, "Query:", TitledBorder.LEADING,
					TitledBorder.DEFAULT_POSITION, new java.awt.Font("Segoe UI", 1, 12)));
			this.jPanelDL.setOpaque(false);
			{
				this.jPanelDLtxt = new JScrollPane();
				this.jPanelDLtxt.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
				this.jPanelDLtxt.setBackground(new java.awt.Color(255, 255, 255));
				this.jPanelDLtxt.setSize(251, 129);
			}
			gl_jPanelDL.setHorizontalGroup(gl_jPanelDL.createSequentialGroup()
					.addComponent(this.jPanelDLtxt, 0, 315, Short.MAX_VALUE)
					.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
					.addComponent(getJPanelConstructors(), GroupLayout.PREFERRED_SIZE, 99, GroupLayout.PREFERRED_SIZE));
			gl_jPanelDL.setVerticalGroup(gl_jPanelDL.createParallelGroup()
					.addComponent(this.jPanelDLtxt, GroupLayout.Alignment.LEADING, 0, 114, Short.MAX_VALUE)
					.addComponent(getJPanelConstructors(), GroupLayout.Alignment.LEADING, 0, 114, Short.MAX_VALUE));
			gl_jPanelDL.linkSize(SwingConstants.VERTICAL, new Component[]{this.jPanelDLtxt, getJPanelConstructors()});
		}

		return this.jPanelDL;
	}

	private JLabel getJLabelConstructors() {
		if (this.jLabelConstructors == null) {
			this.jLabelConstructors = new JLabel();
			this.jLabelConstructors.setText("Constructors");
			this.jLabelConstructors.setFont(new java.awt.Font("Lucida Grande", 0, 10));
		}
		return this.jLabelConstructors;
	}

	private JPanel getJPanelConstructors() {
		if (this.jPanelConstructors == null) {
			this.jPanelConstructors = new JPanel();
			final GroupLayout gl_jPanelConstructors = new GroupLayout(this.jPanelConstructors);
			this.jPanelConstructors.setLayout(gl_jPanelConstructors);
			this.jPanelConstructors.setBackground(new java.awt.Color(255, 255, 255));
			this.jPanelConstructors.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
			this.jPanelConstructors.setSize(80, 129);
			gl_jPanelConstructors.setHorizontalGroup(gl_jPanelConstructors
					.createSequentialGroup()
					.addContainerGap()
					.addGroup(
							gl_jPanelConstructors
							.createParallelGroup()
							.addGroup(
									GroupLayout.Alignment.LEADING,
									gl_jPanelConstructors
									.createSequentialGroup()
									.addComponent(getJLabelConstructors(), GroupLayout.PREFERRED_SIZE,
											GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
											.addGap(0, 8, Short.MAX_VALUE))
											.addGroup(
													gl_jPanelConstructors
													.createSequentialGroup()
													.addComponent(getJButtonOr(), GroupLayout.PREFERRED_SIZE, 65,
															GroupLayout.PREFERRED_SIZE).addGap(0, 0, Short.MAX_VALUE))
															.addGroup(
																	gl_jPanelConstructors
																	.createSequentialGroup()
																	.addComponent(getJButtonAnd(), GroupLayout.PREFERRED_SIZE,
																			GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
																			.addGap(0, 0, Short.MAX_VALUE))
																			.addGroup(
																					GroupLayout.Alignment.LEADING,
																					gl_jPanelConstructors
																					.createSequentialGroup()
																					.addComponent(getJButtonNot(), GroupLayout.PREFERRED_SIZE, 65,
																							GroupLayout.PREFERRED_SIZE).addGap(0, 0, Short.MAX_VALUE)))
																							.addContainerGap(20, 20));
			gl_jPanelConstructors.linkSize(SwingConstants.HORIZONTAL, new Component[]{getJButtonAnd(),
					getJButtonNot(), getJButtonOr()});
			gl_jPanelConstructors.setVerticalGroup(gl_jPanelConstructors
					.createSequentialGroup()
					.addComponent(getJLabelConstructors(), GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE,
							GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
							.addComponent(getJButtonOr(), GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
							.addComponent(getJButtonAnd(), GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
							.addComponent(getJButtonNot(), GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 0, Short.MAX_VALUE));
			gl_jPanelConstructors.linkSize(SwingConstants.VERTICAL, new Component[]{getJButtonAnd(),
					getJButtonNot(), getJButtonOr()});
		}
		return this.jPanelConstructors;
	}

	private JButton getJButtonOr() {
		if (this.jButtonOr == null) {
			this.jButtonOr = new JButton();
			this.jButtonOr.setText("Or");
			this.jButtonOr.setFont(new java.awt.Font("Dialog", 0, 11));
		}
		return this.jButtonOr;
	}

	private JButton getJButtonAnd() {
		if (this.jButtonAnd == null) {
			this.jButtonAnd = new JButton();
			this.jButtonAnd.setText("And");
			this.jButtonAnd.setFont(new java.awt.Font("Dialog", 0, 11));
		}
		return this.jButtonAnd;
	}

	private JButton getJButtonNot() {
		if (this.jButtonNot == null) {
			this.jButtonNot = new JButton();
			this.jButtonNot.setText("Not");
			this.jButtonNot.setFont(new java.awt.Font("Dialog", 0, 11));
		}
		return this.jButtonNot;
	}

	public void updateTxtDLArea(final String conceptName) {
		this.txtAreaDL.append(conceptName);
	}

	private JPanel getJPanelGraph() {
		if (this.jPanelGraph == null) {
			this.jPanelGraph = new JPanel();
			final GroupLayout gl_jPanelGraph = new GroupLayout(this.jPanelGraph);
			this.jPanelGraph.setLayout(gl_jPanelGraph);
			this.jPanelGraph.setPreferredSize(new java.awt.Dimension(416, 582));
			this.jPanelGraph.setBackground(new java.awt.Color(255, 255, 255));
			gl_jPanelGraph.setHorizontalGroup(gl_jPanelGraph
					.createParallelGroup()
					.addGroup(
							GroupLayout.Alignment.LEADING,
							gl_jPanelGraph
							.createSequentialGroup()
							.addComponent(getJPanelLegend(), 0, 201, Short.MAX_VALUE)
							.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 1,
									GroupLayout.PREFERRED_SIZE)
									.addComponent(getJPanelDeepControl(), 0, 201, Short.MAX_VALUE)
									.addGap(0, 6, GroupLayout.PREFERRED_SIZE))
									.addComponent(this.jPanelGraphDisplay, GroupLayout.Alignment.LEADING, 0, 418, Short.MAX_VALUE));
			gl_jPanelGraph.linkSize(SwingConstants.HORIZONTAL, new Component[]{getJPanelLegend(),
					getJPanelDeepControl()});
			gl_jPanelGraph.setVerticalGroup(gl_jPanelGraph
					.createSequentialGroup()
					.addComponent(this.jPanelGraphDisplay, GroupLayout.PREFERRED_SIZE, 457, GroupLayout.PREFERRED_SIZE)
					.addGroup(
							gl_jPanelGraph
							.createParallelGroup()
							.addGroup(
									gl_jPanelGraph
									.createSequentialGroup()
									.addGap(0, 0, Short.MAX_VALUE)
									.addComponent(getJPanelLegend(), GroupLayout.PREFERRED_SIZE, 130,
											GroupLayout.PREFERRED_SIZE))
											.addGroup(
													gl_jPanelGraph
													.createSequentialGroup()
													.addGap(0, 0, Short.MAX_VALUE)
													.addComponent(getJPanelDeepControl(), GroupLayout.PREFERRED_SIZE,
															130, GroupLayout.PREFERRED_SIZE))));
			gl_jPanelGraph.linkSize(SwingConstants.VERTICAL, new Component[]{getJPanelLegend(),
					getJPanelDeepControl()});
		}
		return this.jPanelGraph;
	}

	private PanelDisplayGraph getJPanelGraphDisplay() {
		if (this.jPanelGraphDisplay == null) {
			this.jPanelGraphDisplay = new PanelDisplayGraph(this);
			this.jPanelGraphDisplay.setForeground(new java.awt.Color(255, 255, 255));
			this.jPanelGraphDisplay.setBackground(new java.awt.Color(255, 255, 255));
			this.jPanelGraphDisplay.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
		}

		return this.jPanelGraphDisplay;
	}

	private PanelLegend getJPanelLegend() {
		if (this.jPanelLegend == null) {
			final String lengend = buildLegend();

			this.jPanelLegend = new PanelLegend();
			this.jPanelLegend.setText(lengend);

		}

		return this.jPanelLegend;
	}

	private PanelDeepControl getJPanelDeepControl() {
		if (this.jPanelDeepControl == null) {
			this.jPanelDeepControl = new PanelDeepControl();
			jPanelDeepControl.add(getJLabelTTLIntra());

			jTextFieldTTLIntra = new JTextField();
			jTextFieldTTLIntra.setLocation(new Point(10, 10));
			jTextFieldTTLIntra.setAlignmentY(Component.BOTTOM_ALIGNMENT);
			jTextFieldTTLIntra.setAlignmentX(Component.LEFT_ALIGNMENT);
			jTextFieldTTLIntra.setHorizontalAlignment(SwingConstants.CENTER);
			jPanelDeepControl.add(jTextFieldTTLIntra);
			jTextFieldTTLIntra.setColumns(10);
			jPanelDeepControl.add(getJLabelTTLInter());
			jPanelDeepControl.add(getJTextFieldTTLInter());

			buildDeepControl();
		}
		return this.jPanelDeepControl;
	}

	private JButton getJButtonClear() {
		if (this.jButtonClear == null) {
			this.jButtonClear = new JButton();
			this.jButtonClear.setText("Clear Area");
			this.jButtonClear.addMouseListener(new java.awt.event.MouseAdapter() {
				@Override
				public void mouseClicked(final java.awt.event.MouseEvent e) {
					PanelVisualQuery.this.txtAreaDL.setText("");
				}
			});
		}
		return this.jButtonClear;
	}

	private JScrollPane getJScrollPaneResults() {
		if (this.jScrollPaneResults == null) {
			this.jScrollPaneResults = new JScrollPane();
			this.jScrollPaneResults.setBorder(BorderFactory.createTitledBorder(null, "Results", TitledBorder.LEADING,
					TitledBorder.DEFAULT_POSITION, new java.awt.Font("Segoe UI", 1, 12)));
			this.jScrollPaneResults.setViewportView(getJPanel1());
		}
		return this.jScrollPaneResults;
	}

	private PanelQueryResults getJPanel1() {
		if (this.jPanelResults == null) {
			this.jPanelResults = new PanelQueryResults();
			this.jPanelResults.setPreferredSize(new java.awt.Dimension(420, 154));
		}
		return this.jPanelResults;
	}

	private void buildDeepControl() {
		// Get the GraphDistanceFilter.
		final GraphDistanceFilter filter = this.jPanelGraphDisplay.getOntologyDisplay().getDistanceFilter();

		final GridBagConstraints constraints = new GridBagConstraints();
		constraints.anchor = GridBagConstraints.FIRST_LINE_START;

		// Create the label.
		final JLabel label = new JLabel("Level Numbers: ");

		// Create the spinner and its model.
		final SpinnerNumberModel model = new SpinnerNumberModel(filter.getDistance(), 0, null, 1);
		this.jPanelGraphDisplay.setSpinner(new JSpinner());
		this.jPanelGraphDisplay.getSpinner().addChangeListener(this.jPanelGraphDisplay);
		this.jPanelGraphDisplay.getSpinner().setModel(model);

		// Add the label and the spinner to the panel.
		constraints.gridx = 0;
		constraints.gridy = 0;
		this.jPanelDeepControl.add(label, constraints);
		constraints.gridx = 1;
		constraints.weighty = 1;
		this.jPanelDeepControl.add(this.jPanelGraphDisplay.getSpinner(), constraints);

		// Set the background of the panel.
		this.jPanelDeepControl.setBackground(this.jPanelGraphDisplay.getOntologyDisplay().getBackground());
	}

	private Vector<String> checkProperties(final String className) {
		final Vector<String> properties = new Vector<String>();
		for (int i = 0; i < this.ontologyProperties.size(); i++) {
			final ExtendedIterator domains = this.ontologyProperties.elementAt(i).listDomain();
			while (domains.hasNext()) {
				final OntResource domain = (OntResource) domains.next();
				final String domainName = domain.getLocalName();
				if (className.equals(domainName)) {
					properties.add(this.ontologyProperties.elementAt(i).getLocalName());
					break;
				}
			}
		}
		return properties;
	}

	private String buildLegend() {
		final String nodeColor = Integer.toHexString(PrefuseConstants.NODE_COLOR_CLASS & 0x00ffffff);
		final String nodeSelected = Integer.toHexString(PrefuseConstants.NODE_COLOR_SELECTED & 0x00ffffff);
		final String nodeHighlighted = Integer.toHexString(PrefuseConstants.NODE_COLOR_HIGHLIGHTED & 0x00ffffff);
		final String nodeSearch = Integer.toHexString(PrefuseConstants.NODE_COLOR_SEARCH & 0x00ffffff);

		final StringBuilder sb = new StringBuilder();
		sb.append("<html><body>");
		sb.append("<table>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeColor).append("\" width=\"9px\"/>");
		sb.append("<td>OWL Class</td>");
		sb.append("</tr>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeSelected).append("\"/>");
		sb.append("<td>Selected Node</td>");
		sb.append("</tr>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeHighlighted).append("\"/>");;
		sb.append("<td>Selected Neighbors Node</td>");
		sb.append("</tr>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeSearch).append("\"/>");
		sb.append("<td>Search Result</td>");
		sb.append("</tr>");
		sb.append("</body></html");

		return sb.toString();
	}

	private void initializeOntology() {
		final SpeedLocalOntology OWL_FILE = CommunicationManager.getInstance().getSourceOntology();
		final OntModel ontology = ModelFactory.createOntologyModel();
		this.ontologyProperties.clear();

		try {
			final String ontologyLocation = OWL_FILE.ontology.getLocation();
			ontology.read(new InputStreamReader(new FileInputStream(ontologyLocation)), "");
		} catch (final FileNotFoundException e) {
			JOptionPane.showMessageDialog(null, "File not Found");
		}

		this.arrayListOntologyElements = new ArrayList<String>();

		final Iterator<?> prop = ontology.listDatatypeProperties();

		while (prop.hasNext()) {
			this.ontologyProperties.add((OntProperty) prop.next());
		}

		for (final Iterator<?> it = ontology.listNamedClasses(); it.hasNext();) {
			final OntClass c = (OntClass) it.next();

			if (c.isHierarchyRoot()) {
				printClassTree(c, "", ontology);
			}
		}
		this.jScrollPaneHierarchicalView.setViewportView(getListOntology());
	}

	private void printClassTree(final OntClass cls, final String indentation, final OntModel ontology) {
		if (!this.arrayListOntologyElements.contains(cls.getLocalName())) {

			this.ontElementsVector.add(indentation + Standards.CONCEPTUNICODE + cls.getLocalName() + "\n");

			final Vector<String> properties = checkProperties(cls.getLocalName());
			for (int i = 0; i < properties.size(); i++) {
				this.ontElementsVector.add(indentation + "   " + Standards.MARKERUNICODE + properties.elementAt(i)
						+ "\n");
			}

			this.arrayListOntologyElements.add(cls.getLocalName());
		}

		final Iterator<?> it = cls.listSubClasses();

		while (it.hasNext()) {
			printClassTree((OntClass) it.next(), indentation + "     ", ontology);
		}
	}

	private JList getListOntology() {
		this.jListOntology = new JList(this.ontElementsVector);
		this.jListOntology.addMouseListener(new java.awt.event.MouseAdapter() {
			@Override
			public void mousePressed(final java.awt.event.MouseEvent e) {
				if (e.getClickCount() == 2) {
					final String wordOfOntology = PanelVisualQuery.this.jListOntology.getSelectedValue().toString();
					if (wordOfOntology.contains(Standards.CONCEPTUNICODE)) {
						final String conceptOntology = wordOfOntology.substring(
								wordOfOntology.indexOf(Standards.CONCEPTUNICODE) + 1, wordOfOntology.indexOf("\n"));
						PanelVisualQuery.this.txtAreaDL.append(conceptOntology);
					}

				}
			}
		});

		return this.jListOntology;
	}

	private void submitQueryDL() {
		if (this.txtAreaDL.getText().isEmpty()) {
			SwingUtils.errorMessage(new JFrame(), "Unable to process a empty query.", "Query error!");
		}
		
		this.jProgressBarResults.setIndeterminate(true);
		
		try{
			final Thread treadExecuteQuery = new Thread(new Runnable() {
				@Override
				public void run() {
					
					PanelVisualQuery.this.jPanelResults.updateRows(new ArrayList<InstanceResult>());
					final List<EnrichmentType> enrichmentVariables = buildEnrichmentVariablesList();
					PanelVisualQuery.this.queryManager = new QueryManager();
					final String dlQuery = PanelVisualQuery.this.txtAreaDL.getText();
					final int TTLIntra = Integer.parseInt(PanelVisualQuery.this.jTextFieldTTLIntra.getText());
					final int TTLInter = Integer.parseInt(PanelVisualQuery.this.jTextFieldTTLInter.getText());

					if (dlQuery.length() > 0) {
						System.out.println("DL Query: " + dlQuery);
						final Map<Address, QueryResult> queryResults = PanelVisualQuery.this.queryManager.executeQueryDL(
								dlQuery, enrichmentVariables, TTLIntra, TTLInter);

						if (!queryResults.isEmpty()) {
							final Map<Integer, InstanceResult> results = PanelVisualQuery.this.queryManager
							.processResults(queryResults);

							if (results.isEmpty()) {
								SwingUtils
								.infoMessage(new Frame(), "No results found for query: " + dlQuery, "Query Info.");
							}

							PanelVisualQuery.this.jPanelResults.setResultsMap(results);

							final List<InstanceResult> instances = PanelVisualQuery.this.queryManager
							.buildResultsTree(results);
							PanelVisualQuery.this.jPanelResults.updateRows(instances);
						} else {
							PanelVisualQuery.this.jPanelResults.updateRows(new ArrayList<InstanceResult>());
							SwingUtils.infoMessage(new Frame(), "No results found for query: " + dlQuery, "Query Info.");
						}
					}
					synchronized (PanelVisualQuery.this.mutex) {
						PanelVisualQuery.this.mutex.notify();
					}
				}
			});
			treadExecuteQuery.start();

		} catch (NumberFormatException e){
			SwingUtils.errorMessage(new JFrame(), "Both TTL Intra-cluster and TTL Inter-cluster must be integer.", "Query error!");
		}

		final Thread threadStopProgressBar = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (PanelVisualQuery.this.mutex) {
					try {
						PanelVisualQuery.this.mutex.wait();
						PanelVisualQuery.this.jProgressBarResults.setIndeterminate(false);
					} catch (final InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});

		threadStopProgressBar.start();
	}

	private List<EnrichmentType> buildEnrichmentVariablesList() {
		final List<EnrichmentType> enrichmentVariables = new ArrayList<EnrichmentType>();
		final Enumeration<?> elements = this.jPanelEnrichingVariables.getVariablesPriority().elements();

		while (elements.hasMoreElements()) {
			final String element = (String) elements.nextElement();
			for (final EnrichmentType enrichmentType : EnrichmentType.values()) {
				if (enrichmentType.getType().equalsIgnoreCase(element)) {
					enrichmentVariables.add(enrichmentType);
					break;
				}
			}
		}

		return enrichmentVariables;
	}

	private JPanel getJPanelProgressInfor() {
		if (this.jPanelProgressInfor == null) {
			this.jPanelProgressInfor = new JPanel();
			final GroupLayout gl_jPanelProgressInfor = new GroupLayout(this.jPanelProgressInfor);
			this.jPanelProgressInfor.setLayout(gl_jPanelProgressInfor);
			gl_jPanelProgressInfor.setHorizontalGroup(gl_jPanelProgressInfor.createSequentialGroup()
					.addComponent(getJProgressBarResults(), 0, 432, Short.MAX_VALUE));
			gl_jPanelProgressInfor.setVerticalGroup(gl_jPanelProgressInfor.createSequentialGroup()
					.addComponent(getJProgressBarResults(), 0, 25, Short.MAX_VALUE).addGap(6));
		}
		return this.jPanelProgressInfor;
	}

	private JProgressBar getJProgressBarResults() {
		if (this.jProgressBarResults == null) {
			this.jProgressBarResults = new JProgressBar();
		}
		return this.jProgressBarResults;
	}
	private JTextField getJTextFieldTTLInter() {
		if (jTextFieldTTLInter == null) {
			jTextFieldTTLInter = new JTextField();
			jTextFieldTTLInter.setColumns(10);
		}
		return jTextFieldTTLInter;
	}
	private JLabel getJLabelTTLIntra() {
		if (jLabelTTLIntra == null) {
			jLabelTTLIntra = new JLabel("TTL Intra-cluster:");
		}
		return jLabelTTLIntra;
	}
	private JLabel getJLabelTTLInter() {
		if (jLabelTTLInter == null) {
			jLabelTTLInter = new JLabel("TTL Inter-cluster:");
		}
		return jLabelTTLInter;
	}
}
